package cn.imatu.framework.model;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.imatu.framework.enums.BoolEnum;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.mapstruct.Named;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author shenguangyang
 */
public interface BaseAssembly {
    String BOOL_TO_STR = "boolToStr";
    String STR_TO_BOOL = "strToBool";
    String STR_TO_LIST = "strToList";
    String STR_TO_SET = "strToSet";
    String SET_TO_STR = "setToStr";
    String SET_LONG_TO_STR = "setLongToStr";
    String JSON_STR_TO_LIST = "jsonStrToList";
    String JSON_STR_TO_LIST_LONG = "jsonStrToListLong";
    String JSON_STR_TO_SET = "jsonStrToSet";
    String ARRAY_TO_STR = "arrayToStr";
    String ARRAY_TO_LIST = "arrayToList";
    String LIST_TO_STR = "listToStr";
    String LIST_TO_JSON_STR = "listToJsonStr";
    String SET_TO_JSON_STR = "setToJsonStr";
    String LONG_TO_DATE = "longToDate";
    String OBJECT_TO_JSON_STR = "objectToJsonStr";
    String JSON_OBJECT_TO_STR = "jsonObjectToStr";
    String STR_TO_JSON_OBJECT = "strToJsonObject";

    @Named(OBJECT_TO_JSON_STR)
    default String objectToJsonStr(Object value) {
        return JSON.toJSONString(value);
    }

    @Named(JSON_OBJECT_TO_STR)
    default String jsonObjectToStr(JSONObject value) {
        if (value == null) {
            return null;
        }
        return value.toJSONString();
    }

    @Named(STR_TO_JSON_OBJECT)
    default JSONObject jsonObjectToStr(String value) {
        if (StrUtil.isEmpty(value)) {
            return null;
        }
        return JSON.parseObject(value);
    }


    @Named(JSON_STR_TO_LIST)
    default List<String> jsonStrToList(String value) {
        if (StringUtils.isEmpty(value)) {
            return Collections.emptyList();
        }
        return JSON.parseArray(value, String.class);
    }

    @Named(JSON_STR_TO_LIST_LONG)
    default List<Long> jsonStrToListLong(String value) {
        if (StringUtils.isEmpty(value)) {
            return Collections.emptyList();
        }
        return JSON.parseArray(value, Long.class);
    }

    @Named(JSON_STR_TO_SET)
    default Set<String> jsonStrToSet(String value) {
        if (StringUtils.isEmpty(value)) {
            return Collections.emptySet();
        }
        return new HashSet<>(JSON.parseArray(value, String.class));
    }

    @Named(BOOL_TO_STR)
    default String boolToStr(Boolean value) {
        return BoolEnum.of(value).getCode();
    }

    @Named(STR_TO_BOOL)
    default Boolean strToBool(String value) {
        return BoolEnum.of(value) == BoolEnum.TRUE;
    }

    @Named(STR_TO_LIST)
    default List<String> strToList(String value) {
        if (StringUtils.isEmpty(value)) {
            return Collections.emptyList();
        }
        return Arrays.stream(value.split(",")).collect(Collectors.toList());
    }

    @Named(STR_TO_SET)
    default Set<String> strToSet(String value) {
        if (StringUtils.isEmpty(value)) {
            return Collections.emptySet();
        }
        return Arrays.stream(value.split(",")).collect(Collectors.toSet());
    }

    @Named(ARRAY_TO_STR)
    default String arrayToStr(Long[] value) {
        return Arrays.stream(value).map(String::valueOf).collect(Collectors.joining(","));
    }

    @Named(LIST_TO_STR)
    default String listToStr(List<String> value) {
        if (Objects.isNull(value)) {
            return null;
        }
        return String.join(",", value);
    }

    @Named(SET_TO_STR)
    default String setToStr(Set<String> value) {
        if (Objects.isNull(value)) {
            return null;
        }
        return String.join(",", value);
    }

    @Named(SET_LONG_TO_STR)
    default String setLongToStr(Set<Long> value) {
        if (Objects.isNull(value)) {
            return null;
        }
        return value.stream().map(String::valueOf).collect(Collectors.joining(","));
    }

    @Named(LIST_TO_JSON_STR)
    default String listToJsonStr(Collection<?> value) {
        if (CollUtil.isEmpty(value)) {
            return null;
        }
        return JSON.toJSONString(value);
    }

    @Named(SET_TO_JSON_STR)
    default String setToJsonStr(Set<String> value) {
        if (CollUtil.isEmpty(value)) {
            return null;
        }
        return JSON.toJSONString(value);
    }


    @Named(ARRAY_TO_LIST)
    default List<Long> arrayToList(Long[] value) {
        return Arrays.stream(value).collect(Collectors.toList());
    }

    @Named(LONG_TO_DATE)
    default Date longToDate(Long value) {
        return DateUtil.date(value).toJdkDate();
    }
}
